dot+ Design System
Base v1.1
A functional design language inspired by Uber Base. Now with a two-layer token architecture, Light + Dark themes, and Inter as the primary type family. Use the toggle (top-right) to switch themes.
Primitive + Semantic tokens
Light & Dark
Inter + JetBrains Mono
Base-aligned accent hexes
4 button sizes × 4 shapes
SwiftUI native
What's new in v1.1 — 7 changes for Base parity
1
Two-layer tokens. Primitive (mono + accents) feed Semantic (surface, content, border, state). Components only reference semantic.
2
Light theme added. One token swap, not a rewrite. Both themes ship from day one.
3
Inter replaces Manrope. Neutral grotesque, closer to Uber Move. JetBrains Mono replaces DM Mono.
4
Accents recalibrated to Base's actual hexes: positive #05944F · warning #BB7A00 · negative #E11900 · info #276EF1.
5
Buttons rebuilt. 4 sizes (mini/small/default/large), 4 shapes (default/pill/square/circle), tinted secondary (no border).
6
9pt Micro tier removed. Floor is now 11pt — Dynamic Type and accessibility safe.
7
Base vs dot+ boundary marked. Every component is tagged or .
00 — Architecture
Two-layer token model
Primitive tokens are raw values — never used in components directly. Semantic tokens reference primitives, and vary by theme. Components only ever bind to semantic.
# Layer 1 — primitive (never reference in components)
mono-900 = #0F0F14
mono-50 = #FAFAFC
# Layer 2 — semantic (varies per theme)
surface.primary = mono-900 (dark) · mono-0 (light)
# Layer 3 — components (only use semantic)
DotCard {'{'} background: surface.secondary {'}'}
mono-900 = #0F0F14
mono-50 = #FAFAFC
# Layer 2 — semantic (varies per theme)
surface.primary = mono-900 (dark) · mono-0 (light)
# Layer 3 — components (only use semantic)
DotCard {'{'} background: surface.secondary {'}'}
01 — Foundation
Primitive colors
12-step mono scale + 4 accents. These are raw values. Components never reference these directly — they reference semantic tokens which point here.
Mono scale — hover for token name
mono-0
mono-50
mono-100
mono-200
mono-300
mono-400
mono-500
mono-600
mono-700
mono-800
mono-900
mono-1000
Accents — recalibrated to Base hexes
accent.positive
#05944F · was #00C851
Success, done, connected
accent.warning
#BB7A00 · was #FFB800
Pending, queued, partial
accent.negative
#E11900 · was #E53E3E
Recording, error, critical
accent.info
#276EF1 · was #2D7FF9
Links, badges, AI model
02 — Foundation
Semantic tokens
The contract between design and code. Components always reference these. The mapping below shows what each token resolves to in Dark vs Light.
| Token | Dark → primitive | Light → primitive | Usage |
|---|---|---|---|
| surface.primary | mono-900 | mono-0 | Screen background |
| surface.secondary | mono-800 | mono-50 | Cards, panels |
| surface.tertiary | mono-700 | mono-100 | Inputs, nested surfaces |
| surface.inverse | mono-50 | mono-1000 | Primary CTAs, inverted |
| content.primary | mono-0 | mono-1000 | Body text, titles |
| content.secondary | mono-300 | mono-600 | Supporting text |
| content.tertiary | mono-500 | mono-500 | Captions, timestamps |
| content.disabled | mono-600 | mono-300 | Disabled, placeholder |
| border.opaque | mono-600 | mono-200 | Hairlines, dividers |
| border.subtle | mono-700 | mono-100 | Internal row dividers |
Side-by-side preview
Dark theme
surface.primary
surface.secondary
surface.tertiary
surface.inverse
border.opaque
Light theme
surface.primary
surface.secondary
surface.tertiary
surface.inverse
border.opaque
03 — Foundation
Typography
Inter for all UI text — neutral grotesque, free, near-Uber-Move proportions. JetBrains Mono for metadata, timestamps, and code. 9pt Micro tier removed; floor is 11pt.
Type scale
type.display
Inter Bold · 32 / 36
Screen titles
Screen titles
dot+ Library
type.headline
Inter Bold · 22 / 28
Section titles, card headers
Section titles, card headers
Meeting Intelligence
type.title
Inter SemiBold · 18 / 24
Nav bar, meeting titles
Nav bar, meeting titles
Golf Course Planning
type.body
Inter Regular · 15 / 22
Body text, descriptions
Body text, descriptions
Stakeout plan reviewed with changes to tee positions, landing areas, and green locations across holes 1 through 9.
type.bodyStrong
Inter SemiBold · 15 / 22
Emphasized body, button text
Emphasized body, button text
Start Recording
type.label
Inter Medium · 13 / 18
List rows, form labels
List rows, form labels
Rodrigo Arvizu · Xhinola
type.caption
JetBrains Mono Regular · 11 / 14
Timestamps, metadata, states
Timestamps, metadata, states
Today · 47m · 2 speakers · Gemini 2.5 Pro
04 — Foundation
Spacing
Strict 4pt base grid. Every spacing value is a multiple of 4.
space.1
4pt
Icon-label gap
space.2
8pt
Within-component padding
space.3
12pt
Card padding, button padding
space.4
16pt
Screen edge margin, between cards
space.5
20pt
Section spacing
space.6
24pt
Major section breaks, nav padding
space.7
32pt
Above section headers
space.8
48pt
Top of screen padding
05 — Foundation
Corner radius
Tight radii. Never exceed 16pt — functional, not playful.
radius.xs
4pt
Tags, badges, micro
radius.sm
8pt
Cards, inputs, buttons
radius.md
12pt
Bottom sheet
radius.lg
16pt
Full-screen sheet (max)
06 — Foundation
Elevation
Dark mode: elevation is shown by surface tonal lift (primary → secondary → tertiary). No drop shadow. Light mode: real shadows. Toggle the theme to see the difference.
shadow.1
Cards (light only)
shadow.2
Popovers, dropdowns
shadow.3
Modals, sheets
07 — Component
DotButton
4 variants × 4 sizes × 4 shapes. Minimum hit target 44×44pt always (extend tap area on mini/small). Haptic .light on tap. No border on secondary — tinted, not outlined.
Variants
Sizes — mini 28 / small 36 / default 48 / large 56
Shapes — default / pill / square / circle
States
08 — Component
DotTag
Renamed from "Pill" to match Base naming. Default is surface.tertiary; semantic variants use solid 16%-tinted fills (no border).
default
done
3 todos
error
Real Estate
connected
limited
REC
Gemini 2.5 Pro
offline
09 — Component
DotCard
Fill-only on dark (no border); 1pt subtle border on light. Internal rows separated by border.subtle hairlines.
Folder list
🏗
Golf Project
7 meetings · 8h 42m
›
🏠
Real Estate
12 meetings · 14h 20m
›
💻
dot+ Development
5 meetings · 6h 11m
›
Meeting rows with status tags
Golf Course Planning
Today · 1h 32m · Bobby Weed
Quintero Strategy
Yesterday · 47m
Site Visit
Mon · 38m
10 — Component
DotInput
48pt height. Tinted fill on surface.tertiary, transparent border default. Focus → accent.info border. Error → accent.negative border.
Required before recording
Stored in iOS Keychain
Click any input to see focus state
API key format is invalid
11 — Component
DotToggle
42×24pt track. On → surface.inverse. Off → border.opaque. Knob inverts to maintain contrast.
iCloud Sync
2.1 GB used
Keep audio files
Delete after analysis to save space
Privacy mode
Gemma only · no cloud upload
Things 3
Not connected
13 — Component
DotTabBar
Not a Base component — Base has no bottom tab bar. This is a dot+ extension following Apple HIG. 80pt height, solid surface (no blur), 1pt top border.
⌂
Home
◫
Library
◈
Ask
⚙
Settings
14 — Guidelines
Motion
Functional only. No spring, no bounce. Shortest duration that reads.
State change
.easeInOut · 0.15s
Toggle, button press
Toggle, button press
Sheet entry
.easeOut · 0.30s
Bottom sheet, modal
Bottom sheet, modal
Tap response
scale(.97) · instant
All interactive
All interactive
15 — Reference
Figma setup checklist
What you need to mirror this system in Figma — in build order.
1. Install fonts · Inter (Google Fonts), JetBrains Mono (Google Fonts) — both free.
2. Figma Variables — collection 1: Primitive · 12 mono swatches + 4 accents. Single mode.
3. Figma Variables — collection 2: Semantic · 2 modes (Dark, Light). Each variable points to a Primitive token, different per mode.
4. Figma Variables — collection 3: Number · space.1–8, radius.xs–lg.
5. Text styles · 7 styles bound to Inter / JetBrains Mono variants per §3.
6. Components · Build in order: Button (variants × sizes × shapes via component properties) → Tag → Input → Toggle → Card → NavBar → TabBar.
7. Plugin · Install Tokens Studio to export Variables → JSON → SwiftUI codegen.